<?php

namespace model\database;

/**
 * Description of PDOConnector
 *
 * @author Damian
 */
class PDOConnector extends Connector{
    /**
     *@readwrite
     * @var \PDO 
     */
    protected $service;
    /**
     * @readwrite
     */
    protected $host;
    /**
     * @readwrite
     */
    protected $type;
    /**
     * @readwrite
     */
    protected $username;
    /**
     * @readwrite
     */
    protected $password;
        /**
     * @readwrite
     */
    protected $schema;
    /**
     * @readwrite
     */
    protected $charset;
    /**
     * @readwrite
     */
    protected $engine;
    /**
     * @readwrite
     */
    protected $port;
    /**
     *
     * @readwrite
     */
    protected $isConnected;
    protected function _isValidService(){
        $isEmpty = empty($this->service);
        $isInstance =  $this->service instanceof \PDO;
        if ($this->isConnected && $isInstance && !$isEmpty){
            return true;
        }
        return false;
    }
    public function __construct($options = array()) {
        parent::__construct($options);
        
    }

    /**
     * 
     * @throws \library\exceptions\model\ExceptionNotConnected
     */
    private function checkConnetion(){
        if (!$this->_isValidService()){
            throw  new \model\exceptions\ExceptionNotConnected();
        }
    }
    public function connect(){
        if (!$this->_isValidService()){
            $dsn = "{$this->type}:dbname={$this->schema};host={$this->host}";
            try {
                $this->service = new \PDO($dsn, $this->username, $this->password);
                $this->service->query('SET NAMES utf8');
		$this->service->query('SET CHARACTER SET utf8');
                $this->isConnected=true;
            } catch (\PDOException $ex) {
                throw new \model\exceptions\ExceptionCannotConnect($ex->getMessage());
            }            
        }
        return $this;
    }
    public function disconnect(){
        if ($this->_isValidService()){
            $this->isConnected=false;
            unset($this->service);
        }
    }


    /**
     * 
     * @param type $sql
     * @return \PDOStatement
     */
    public function executeSQL($sql){
        $this->checkConnetion();
        $result = $this->service->query($sql);
        if ($result===false){
            $error = $this->service->errorInfo();
            throw new \model\exceptions\ExceptionSQLQUery("in query ".$sql." ".$error[2],$error[1]);
        }
        return $result;
    }
    public function getAffectedRows($result=null){
        return $result->rowCount();
    }
    public function fetch($result, $fetchType = Connector::FETCH_BOTH, $className = "stdClass") {
        switch ($fetchType) {
            case Connector::FETCH_NUM: {
                    return $result->fetch(\PDO::FETCH_NUM);
                }
            case Connector::FETCH_ASSOC: {
                    return $result->fetch(\PDO::FETCH_ASSOC);
                }
            case Connector::FETCH_BOTH: {
                    return $result->fetch(\PDO::FETCH_BOTH);
                }
            case Connector::FETCH_OBJECT: {
                    return $result->fetchObject($className);
                }
            default : {
                    throw new \library\exceptions\model\ExceptionWrongQueryArgument("fetchType");
                }
        }
    }

    public function escape($value){
        $this->checkConnetion();
        return $this->service->quote($value);
    }
   public function getLastInsertId($name=null){
        $this->checkConnetion();
        return $this->service->lastInsertId($name);
    }
    /**
     * 
     * @param type $statement 
     * @return \PDOStatement
     */
    public function prepare($statement){
        $this->checkConnetion();
        return $this->service->prepare($statement);
    }

}
